﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;

namespace DigitalImage.softLib {
    public class CKMeansColor {
        public List<Color> elementi=new List<Color>();
        public List<CClusterColor> grupe=new List<CClusterColor>();
        public int brojGrupa=0;
        Random rnd=new Random();

        public void podeliUGRupe(int brojGrupa, double errT) {
            this.brojGrupa=brojGrupa;
            if(brojGrupa==0) return;
            //------------  inicijalizacija -------------
            for(int i=0;i<brojGrupa;i++) {
                int ii=rnd.Next(elementi.Count);
                CClusterColor grupa=new CClusterColor();
                grupa.centar=elementi[ii];
                grupe.Add(grupa);
            }
            //------------- iterativno racunanje centara ---
            for(int it=0;it<100;it++) {
                foreach(CClusterColor grupa in grupe)
                    grupa.elementi=new List<Color>();
                foreach(Color cc in elementi) {
                    int najblizaGrupa=0;
                    for(int i=0;i<brojGrupa;i++) {
                        if(grupe[najblizaGrupa].rastojanje(cc)>
                            grupe[i].rastojanje(cc)) {
                            najblizaGrupa=i;
                        }
                    }
                    grupe[najblizaGrupa].elementi.Add(cc);
                }
                double err=0;
                for(int i=0;i<brojGrupa;i++) {
                    err+=grupe[i].pomeriCentar();
                }
                if(err<errT)
                    break;
            }
        }
    }

    public class CClusterColor {
        public Color centar=Color.FromArgb(0, 0, 0, 0);
        public List<Color> elementi=new List<Color>();

        public double rastojanje(Color c) {
            return Math.Abs(c.R-centar.R)+Math.Abs(c.G-centar.G)+Math.Abs(c.B-centar.B);
        }

        public double pomeriCentar() {
            double sR=0;
            double sG=0;
            double sB=0;
            double retVal=0;
            foreach(Color c in elementi) {
                sR+=c.R;
                sG+=c.G;
                sB+=c.B;
            }
            int n=elementi.Count();
            if(n!=0) {
                Color nCentar=Color.FromArgb(255, (int)(sR/n), (int)(sG/n), (int)(sB/n));
                retVal=rastojanje(nCentar);
                centar=nCentar;
            }
            return retVal;
        }
    }
}
